package com.qing.common.util

import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.transition.AutoTransition
import androidx.transition.ChangeBounds
import androidx.transition.Explode
import androidx.transition.Transition
import androidx.transition.TransitionManager

/**
 * 过渡动画工具类
 *
 * @author qing <br/>
 * 2025/2/22
 */
object TransitionAnimationUtils {

    const val DEFAULT_ANIMATION_DURATION = 500L

    @JvmField
    val DEFAULT_INTERPOLATOR = AccelerateDecelerateInterpolator()

    fun createAutoTransition(
        onStart: (() -> Unit)? = null, onEnd: (() -> Unit)? = null
    ): Transition {
        return AutoTransition().setDuration(DEFAULT_ANIMATION_DURATION)
            .setInterpolator(DEFAULT_INTERPOLATOR).addListener(onStart, onEnd)
    }

    fun applyAutoTransition(sceneRoot: ViewGroup) {
        applyAutoTransition(sceneRoot, null, null)
    }

    fun applyAutoTransition(
        sceneRoot: ViewGroup, onStart: (() -> Unit)? = null, onEnd: (() -> Unit)? = null
    ) {
        TransitionManager.beginDelayedTransition(sceneRoot, createAutoTransition(onStart, onEnd))
    }

    fun createChangeBounds(
        onStart: (() -> Unit)? = null, onEnd: (() -> Unit)? = null
    ): Transition {
        return ChangeBounds().setDuration(DEFAULT_ANIMATION_DURATION)
            .setInterpolator(DEFAULT_INTERPOLATOR).addListener(onStart, onEnd)
    }

    fun applyChangeBoundsTransition(sceneRoot: ViewGroup) {
        applyChangeBoundsTransition(sceneRoot, null, null)
    }

    fun applyChangeBoundsTransition(
        sceneRoot: ViewGroup, onStart: (() -> Unit)? = null, onEnd: (() -> Unit)? = null
    ) {
        TransitionManager.beginDelayedTransition(
            sceneRoot, createChangeBounds(onStart, onEnd)
        )
    }

    fun createExplodeTransition(
        onStart: (() -> Unit)? = null, onEnd: (() -> Unit)? = null
    ): Transition {
        return Explode().setDuration(DEFAULT_ANIMATION_DURATION)
            .setInterpolator(DEFAULT_INTERPOLATOR).addListener(onStart, onEnd)
    }

    fun applyExplodeTransition(sceneRoot: ViewGroup) {
        applyExplodeTransition(sceneRoot, null, null)
    }

    fun applyExplodeTransition(
        sceneRoot: ViewGroup, onStart: (() -> Unit)? = null, onEnd: (() -> Unit)? = null
    ) {
        TransitionManager.beginDelayedTransition(
            sceneRoot, createExplodeTransition(onStart, onEnd)
        )
    }
}

inline fun <reified T : Transition> T.addListener(
    noinline onStart: (() -> Unit)? = null, noinline onEnd: (() -> Unit)? = null
): T {
    addListener(object : Transition.TransitionListener {
        private var isFinished = false

        private fun onFinished() {
            if (!isFinished) {
                isFinished = true
                onEnd?.invoke()
            }
        }

        override fun onTransitionStart(transition: Transition) {
            onStart?.invoke()
        }

        override fun onTransitionEnd(transition: Transition) {
            onFinished()
        }

        override fun onTransitionCancel(transition: Transition) {
            onFinished()
        }

        override fun onTransitionPause(transition: Transition) {
        }

        override fun onTransitionResume(transition: Transition) {}
    })
    return this
}